1 package org.apache.maven.surefire.common.junit4;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import org.apache.maven.surefire.report.ReportEntry;
23 import org.apache.maven.surefire.report.RunListener;
24 import org.apache.maven.surefire.report.SimpleReportEntry;
25 import org.apache.maven.surefire.report.StackTraceWriter;
26 import org.apache.maven.surefire.testset.TestSetFailedException;
27 import org.junit.runner.Description;
28 import org.junit.runner.Result;
29 import org.junit.runner.notification.Failure;
30
31 import static org.apache.maven.surefire.common.junit4.JUnit4ProviderUtil.isFailureInsideJUnitItself;
32 import static org.apache.maven.surefire.common.junit4.JUnit4Reflector.getAnnotatedIgnoreValue;
33 import static org.apache.maven.surefire.report.SimpleReportEntry.assumption;
34 import static org.apache.maven.surefire.report.SimpleReportEntry.ignored;
35 import static org.apache.maven.surefire.report.SimpleReportEntry.withException;
36 import static org.apache.maven.surefire.util.internal.TestClassMethodNameUtils.extractClassName;
37 import static org.apache.maven.surefire.util.internal.TestClassMethodNameUtils.extractMethodName;
38
39
40
41
42
43 public class JUnit4RunListener
44 extends org.junit.runner.notification.RunListener
45 {
46 protected final RunListener reporter;
47
48
49
50
51
52 private final ThreadLocal<Boolean> failureFlag = new InheritableThreadLocal<Boolean>();
53
54
55
56
57
58
59 public JUnit4RunListener( RunListener reporter )
60 {
61 this.reporter = reporter;
62 }
63
64
65
66
67
68
69
70
71 public void testIgnored( Description description )
72 throws Exception
73 {
74 String reason = getAnnotatedIgnoreValue( description );
75 reporter.testSkipped( ignored( getClassName( description ), description.getDisplayName(), reason ) );
76 }
77
78
79
80
81
82
83 public void testStarted( Description description )
84 throws Exception
85 {
86 reporter.testStarting( createReportEntry( description ) );
87 failureFlag.remove();
88 }
89
90
91
92
93
94
95 @SuppressWarnings( { "ThrowableResultOfMethodCallIgnored" } )
96 public void testFailure( Failure failure )
97 throws Exception
98 {
99 String testHeader = failure.getTestHeader();
100 if ( isInsaneJunitNullString( testHeader ) )
101 {
102 testHeader = "Failure when constructing test";
103 }
104
105 ReportEntry report =
106 withException( getClassName( failure.getDescription() ), testHeader, createStackTraceWriter( failure ) );
107
108 if ( failure.getException() instanceof AssertionError )
109 {
110 reporter.testFailed( report );
111 }
112 else
113 {
114 reporter.testError( report );
115 }
116
117 failureFlag.set( true );
118 }
119
120 @SuppressWarnings( "UnusedDeclaration" )
121 public void testAssumptionFailure( Failure failure )
122 {
123 Description desc = failure.getDescription();
124 String test = getClassName( desc );
125 reporter.testAssumptionFailure( assumption( test, desc.getDisplayName(), failure.getMessage() ) );
126 failureFlag.set( true );
127 }
128
129
130
131
132
133
134 public void testFinished( Description description )
135 throws Exception
136 {
137 Boolean failure = failureFlag.get();
138 if ( failure == null )
139 {
140 reporter.testSucceeded( createReportEntry( description ) );
141 }
142 }
143
144
145
146
147 public void testExecutionSkippedByUser()
148 {
149 reporter.testExecutionSkippedByUser();
150 }
151
152 private String getClassName( Description description )
153 {
154 String name = extractDescriptionClassName( description );
155 if ( name == null || isInsaneJunitNullString( name ) )
156 {
157
158 Description subDescription = description.getChildren().get( 0 );
159 if ( subDescription != null )
160 {
161 name = extractDescriptionClassName( subDescription );
162 }
163 if ( name == null )
164 {
165 name = "Test Instantiation Error";
166 }
167 }
168 return name;
169 }
170
171 protected StackTraceWriter createStackTraceWriter( Failure failure )
172 {
173 return new JUnit4StackTraceWriter( failure );
174 }
175
176 protected SimpleReportEntry createReportEntry( Description description )
177 {
178 return new SimpleReportEntry( getClassName( description ), description.getDisplayName() );
179 }
180
181 protected String extractDescriptionClassName( Description description )
182 {
183 return extractClassName( description.getDisplayName() );
184 }
185
186 protected String extractDescriptionMethodName( Description description )
187 {
188 return extractMethodName( description.getDisplayName() );
189 }
190
191 public static void rethrowAnyTestMechanismFailures( Result run )
192 throws TestSetFailedException
193 {
194 for ( Failure failure : run.getFailures() )
195 {
196 if ( isFailureInsideJUnitItself( failure.getDescription() ) )
197 {
198 throw new TestSetFailedException( failure.getTestHeader() + " :: " + failure.getMessage(),
199 failure.getException() );
200 }
201 }
202 }
203
204 private static boolean isInsaneJunitNullString( String value )
205 {
206 return "null".equals( value );
207 }
208 }